package com.media.publish.utils;

import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;

import com.baselibrary.manager.AppManager;
import com.baselibrary.net.interceptor.LoggingInterceptor;
import com.baselibrary.utils.AppUtils;
import com.baselibrary.utils.GsonUtils;
import com.baselibrary.utils.SpUtils;
import com.baselibrary.utils.ToastUtils;

import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;


public class OkhttpUtils {
    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    private static OkhttpUtils instance;
    private final OkHttpClient okHttpClient;
    private Context context;

    //构造方法要私有化
    private OkhttpUtils(Context context) {
        this.context = context;
        //创建OkhttpClient对象
        okHttpClient = new OkHttpClient.Builder().
                addNetworkInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Request request = chain.request();
                        Response response = chain.proceed(request);
                        return response;
                    }
                })
                .addInterceptor(new LoggingInterceptor())
                .connectTimeout(15, TimeUnit.SECONDS)//连接超时
                .writeTimeout(20, TimeUnit.SECONDS)//写入超时
                .readTimeout(20, TimeUnit.SECONDS)//读取超时
                .build();
        handler = new Handler(Looper.getMainLooper());
    }

    //单例模式
    //懒汉式
    public static OkhttpUtils getInstance(Context context) {
        if (instance == null) {
            instance = new OkhttpUtils(context);
        }
        return instance;
    }

    private Handler handler = new Handler(Looper.getMainLooper());

    public Handler getHandler() {
        return handler;
    }

    /**
     * GET请求
     *
     * @param url
     */
    private OkHttpClient client;

    private void initOkHttpClient() {
        if (client == null) {
            client = new OkHttpClient.Builder().build();
        }
    }

    /**
     * doget 请求
     * tClass 最终要解析的对象
     *
     * @param url
     * @param params
     * @param callback
     */
    public <T> void doGet(String url, Map<String, String> params, final Class<T> tClass, final BaseCallback<T> callback) {
        if (params != null) {
            StringBuilder sb = new StringBuilder();
            sb.append("?");
            for (Map.Entry<String, String> entry : params.entrySet()) {
                sb.append(entry.getKey());
                sb.append("=");
                sb.append(entry.getValue());
                sb.append("&");
            }
            String s = sb.toString();
            String strParam = s.substring(0, s.length() - 1);
            url += strParam;

        }

        Request request = new Request.Builder().
                url(url).
                addHeader("token", SpUtils.getInstance().getUserToken()).
                addHeader("platform", "android").
                addHeader("platVersion", AppUtils.getVersionName()).
                build();

        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull final Call call, @NotNull final IOException e) {

                handler.post(new Runnable() {//处理返回错误的数据，参数后期更改
                    @Override
                    public void run() {
                        callback.onFailure(call, e);
                    }
                });
            }

            @Override
            public void onResponse(@NotNull final Call call, @NotNull final Response response) throws IOException {
                String string = response.body().string();

                try {
                    JSONObject jsonObject = new JSONObject(string);
                    if (jsonObject.optInt("code") == 404) {
                        AppManager.getAppManager().openLoginPage(Intent.FLAG_ACTIVITY_NEW_TASK);
                        return;
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                    return;
                }


                sendUiThread(call, callback, string, tClass);

            }


        });
    }

    /**
     * body  key/value形式
     *
     * @param url
     * @param paramsMap
     */
    public <T> void doPost(final String url, HashMap<String, String> paramsMap, final Class<T> tClass, final BaseCallback<T> callback) {
        FormBody.Builder builder = new FormBody.Builder();
        Set<String> mKeySet = paramsMap.keySet();
        for (String key : mKeySet) {
            builder.add(key, Objects.requireNonNull(paramsMap.get(key)));
        }

        //post请求
        Request mRequest = new Request.Builder()
                .url(url)
                .addHeader("token", SpUtils.getInstance().getUserToken())
                .addHeader("platform", "android")
                .addHeader("platVersion", AppUtils.getVersionName())
                .post(builder.build())
                .build();
        okHttpClient.newCall(mRequest).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull final Call call, @NotNull final IOException e) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        callback.onFailure(call, e);
                    }
                });
            }

            @Override
            public void onResponse(@NotNull final Call call, @NotNull final Response response) throws IOException {
                String string = response.body().string();

                try {
                    JSONObject jsonObject = new JSONObject(string);
                    if (jsonObject.optInt("code") == 404) {
                        AppManager.getAppManager().openLoginPage(Intent.FLAG_ACTIVITY_NEW_TASK);
                        return;
                    }
                    if (url.contains("http://39.107.247.82:30001")) {
                        partyBSendUiThread(call, callback, string, tClass);
                    } else {
                        sendUiThread(call, callback, string, tClass);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }


    /**
     * application/json 形式
     *
     * @param url
     * @param json
     */
    public <T> void doPost(final String url, String json, final Class<T> tClass, final BaseCallback<T> callback) {
        RequestBody mRequestBody = RequestBody.create(JSON, json);
        Request mRequest = new Request.Builder()
                .url(url)
                .addHeader("token", SpUtils.getInstance().getUserToken())
                .addHeader("platform", "android")
                .addHeader("platVersion",AppUtils.getVersionName())
                .post(mRequestBody)
                .build();
        okHttpClient.newCall(mRequest).enqueue(new Callback() {
            @Override
            public void onFailure(final Call call, final IOException e) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        callback.onFailure(call, e);
                    }
                });
            }

            @Override
            public void onResponse(final Call call, final Response response) throws IOException {
                final String string = response.body().string();

                try {
                    JSONObject jsonObject = new JSONObject(string);
                    if (jsonObject.optInt("code") == 404) {
                        AppManager.getAppManager().openLoginPage(Intent.FLAG_ACTIVITY_NEW_TASK);
                        return;
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                    return;
                }

                //证明是乙方接口
                if (url.contains("http://39.107.247.82:30001")) {
                    partyBSendUiThread(call, callback, string, tClass);
                } else {
                    sendUiThread(call, callback, string, tClass);
                }

            }

        });
    }


    /**
     * application/json 形式
     *
     * @param url
     * @param json
     */
    public <T> void doPost(final String url, String json, String token, final Class<T> tClass, final BaseCallback<T> callback) {
        RequestBody mRequestBody = RequestBody.create(JSON, json);
        Request mRequest = new Request.Builder()
                .url(url)
                .addHeader("token", token)
                .addHeader("platform", "android")
                .addHeader("platVersion", AppUtils.getVersionName())
                .post(mRequestBody)
                .build();
        okHttpClient.newCall(mRequest).enqueue(new Callback() {
            @Override
            public void onFailure(final Call call, final IOException e) {

                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        callback.onFailure(call, e);
                    }
                });
            }

            @Override
            public void onResponse(final Call call, final Response response) throws IOException {
                final String string = response.body().string();
                try {
                    JSONObject jsonObject = new JSONObject(string);
                    if (jsonObject.optInt("code") == 404) {
                        AppManager.getAppManager().openLoginPage(Intent.FLAG_ACTIVITY_NEW_TASK);
                        return;
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                    return;
                }

                //证明是乙方接口
                if (url.contains("http://39.107.247.82:30001")) {
                    partyBSendUiThread(call, callback, string, tClass);
                } else {
                    sendUiThread(call, callback, string, tClass);
                }

            }

        });
    }


    private <T> void sendOtherServer(final Call call, final BaseCallback callback, final String string, final Class<T> tClass) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                try {
                    if (TextUtils.isEmpty(string)) {
                        ToastUtils.showShort(context, "请求错误");
                        return;
                    }
                    BaseResp o = GsonUtils.parseJsonToBean(string, BaseResp.class);

                    T t = GsonUtils.parseJsonToBean(string, tClass);
                    callback.onResponse(call, t);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private <T> void sendUiThread(final Call call, final BaseCallback callback, final String string, final Class<T> tClass) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                try {
                    if (TextUtils.isEmpty(string)) {
                        return;
                    }
                    BaseResp o = GsonUtils.parseJsonToBean(string, BaseResp.class);
                    if (o.getCode() != 200) {
                        ToastUtils.showShort(context, o.getMessage());
                        return;
                    }


                    T t = GsonUtils.parseJsonToBean(string, tClass);
                    callback.onResponse(call, t);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 乙方接口
     *
     * @param call
     * @param callback
     * @param string
     * @param tClass
     * @param <T>
     */
    private <T> void partyBSendUiThread(final Call call, final BaseCallback callback, final String string, final Class<T> tClass) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                try {
                    T t = GsonUtils.parseJsonToBean(string, tClass);
                    callback.onResponse(call, t);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public HashMap<String, String> createParamsMap() {
        //储存用户token
        HashMap<String, String> mParamsMap = new HashMap<>();
        return mParamsMap;
    }

    /**
     * 上传文件至服务器
     *
     * @param url
     */
    //上传文件（图片）
    public <T> void upLoadImage(String url, String path, final Class<T> tClass, final BaseCallback<T> callback) {//url 要上传的地址。path 要上传的文件路径


        //媒体类型
        MediaType mediaType = MediaType.parse("image/*");
        //multipartbody
        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        File file = new File(path);
        MultipartBody multipartBody = builder.addFormDataPart("file", file.getName(), RequestBody.create(mediaType, file)).build();


        Request mRequest = new Request.Builder().url(url).post(multipartBody).build();


        okHttpClient.newCall(mRequest).enqueue(new Callback() {
            @Override
            public void onFailure(final Call call, final IOException e) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        callback.onFailure(call, e);
                    }
                });
            }

            @Override
            public void onResponse(final Call call, final Response response) throws IOException {
                String string = response.body().string();

                sendOtherServer(call, callback, string, tClass);
//
            }

        });

    }

    public <T> void upLoadMultiImage(String url, ArrayList<String> images, final Class<T> tClass, final BaseCallback<T> callback) {//url 要上传的地址。path 要上传的文件路径


        //媒体类型
        MediaType mediaType = MediaType.parse("image/*");
        //multipartbody
        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        for (String image : images) {
            File file = new File(image);
            builder.addFormDataPart("file", file.getName(), RequestBody.create(mediaType, file));
        }
        MultipartBody multipartBody = builder.build();


        Request mRequest = new Request.Builder().url(url).post(multipartBody).build();


        okHttpClient.newCall(mRequest).enqueue(new Callback() {
            @Override
            public void onFailure(final Call call, final IOException e) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        callback.onFailure(call, e);
                    }
                });
            }

            @Override
            public void onResponse(final Call call, final Response response) throws IOException {
                String string = response.body().string();

                sendOtherServer(call, callback, string, tClass);
//
            }

        });

    }

}